﻿
namespace System.Data.SQL.Linq.Mapping
{
    #region UpdateCheck
    public enum UpdateCheck
    {
        Always,
        Never,
        WhenChanged
    }
    #endregion

    #region AutoSync
    /// <summary>
    /// Used to specify for during insert and update operations when 
    /// a data member should be read back after the operation completes.
    /// </summary> 
    public enum AutoSync
    {
        Default = 0, // Automatically choose
        Always = 1,
        Never = 2,
        OnInsert = 3,
        OnUpdate = 4
    } 
    #endregion

    #region DatabaseAttribute
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public sealed class DatabaseAttribute : Attribute
    {
        public string Name { get; set; }
    }
    #endregion

    #region TableAttribute
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public sealed class TableAttribute : Attribute
    {
        public string Name { get; set; }
    }
    #endregion

    #region InheritanceMappingAttribute
    /// <summary>
    /// Class attribute used to describe an inheritance hierarchy to be mapped. 
    /// For example,
    /// 
    ///     [Table(Name = "People")] 
    ///     [InheritanceMapping(Code = "P", Type = typeof(Person), IsDefault=true)]
    ///     [InheritanceMapping(Code = "C", Type = typeof(Customer))] 
    ///     [InheritanceMapping(Code = "E", Type = typeof(Employee))]
    ///     class Person { ... }
    ///
    /// </summary> 
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    public sealed class InheritanceMappingAttribute : Attribute
    {
        /// <summary>
        /// Discriminator value in store column for this type.
        /// </summary> 
        public object Code { get; set; }
        /// <summary> 
        /// Type to instantiate when Key is matched.
        /// </summary>
        public Type Type { get; set; }
        /// <summary> 
        /// If discriminator value in store column is unrecognized then instantiate this type.
        /// </summary>
        public bool IsDefault { get; set; }
    }
    #endregion

    #region DataAttribute
    public abstract class DataAttribute : Attribute
    {
        public string Name { get; set; }
        public string Storage { get; set; }
    }
    #endregion

    #region ColumnAttribute
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
    public sealed class ColumnAttribute : DataAttribute
    {
        public string DbType { get; set; }
        public string Expression { get; set; }
        public bool IsPrimaryKey { get; set; }
        public bool IsDbGenerated { get; set; }
        public bool IsVersion { get; set; }
        public UpdateCheck UpdateCheck { get; set; }
        public AutoSync AutoSync { get; set; }
        public bool IsDiscriminator { get; set; }
        public bool CanBeNull { get; set; }
    }
    #endregion

    #region AssociationAttribute
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
    public sealed class AssociationAttribute : DataAttribute
    {
        public string ThisKey { get; set; }
        public string OtherKey { get; set; }
        public bool IsUnique { get; set; }
        public bool IsForeignKey { get; set; }
        public string DeleteRule { get; set; }
        public bool DeleteOnNull { get; set; }
    }
    #endregion

    #region FunctionAttribute
    /// <summary> 
    /// Attribute placed on a method mapped to a User Defined Function.
    /// </summary> 
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class FunctionAttribute : Attribute
    {
        public string Name { get; set; }
        public bool IsComposable { get; set; }
    }
    #endregion

    #region ResultTypeAttribute
    /// <summary> 
    /// This attribute is applied to functions returning multiple result types,
    /// to declare the possible result types returned from the function.  For
    /// inheritance types, only the root type of the inheritance hierarchy need
    /// be specified. 
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public sealed class ResultTypeAttribute : Attribute
    {   
        public ResultTypeAttribute(Type type)
        {
            this.Type = type;
        }
        public Type Type { get; private set; }
    }
    #endregion

    #region ParameterAttribute
    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false)]
    public sealed class ParameterAttribute : Attribute
    {
        public string Name { get; set; }
        public string DbType { get; set; }
    } 
    #endregion
}
